/******************************************************************************中
 * @brief: file  : hal.c
 * @Author:   aple
 * @Date: 2022-12-14 18:06:21
 * @LastEditors: aple
 * @LastEditTime: 2023-05-09 16:00:33
 * @Verision: 1.0.0.0
 ******************************************************************************/
#include "bsp.h"
#include "pincfg.h"
#include "framework.h"
#include "key_handle.h"
#include "sys_task.h"

/*****************************************************************************
 * @brief   fun.
 *****************************************************************************/
FUN_LIST_CREAT(KEY_S0);
FUN_LIST_CREAT(KEY_S1);
FUN_LIST_CREAT(KEY_S2);
FUN_LIST_CREAT(KEY_UP);

void key_isr(void);

/*****************************************************************************
 * @brief   micro.
 *****************************************************************************/
#define KEY0_MSK 1
#define KEY1_MSK 2
#define KEY2_MSK 4
#define KEYUP_MSK 8

/*****************************************************************************
 * @brief   var.
 *****************************************************************************/
key8_type key;
extern const key_api_type key_api;
extern const key_opt_type key_opt_list[];

/*****************************************************************************
 * @brief   key init.
 *****************************************************************************/
void key_init(void)
{
	key.series_space_sv = 8;
	key.api = &key_api;
	app_timer_task_add(key_isr);
}
obj_init_order5(key_init);

void key_isr(void)
{
	uint32_t rd = 0;
	static uint8_t cnt=0;
	
	cnt ++;
	cnt &=3;

	if( 0 == cnt)
	{
		if (key_0.in_st())
			rd |= KEY0_MSK;

		if (key_1.in_st())
			rd |= KEY1_MSK;

		if (key_2.in_st())
			rd |= KEY2_MSK;

		if (key_up.in_st())
			rd |= KEYUP_MSK;

		key8_st_sample(&key, rd);
	}
}

void key_task(void)
{
	key8_st_handle(&key, Gst.pulse.pulse_100ms);
}
obj_app_order(key_task);

/*****************************************************************************
 * @brief   key common.
 *****************************************************************************/
void key_down_any(void)
{
	if (2 == key.serial_cnt)
	{
		switch (key.found_edge.uval)
		{
		case KEY0_MSK:
			dbg_puts("key 0 double press !!!" PTCR);
			break;
		case KEY1_MSK:
			dbg_puts("key 1 double press !!!" PTCR);
			break;
		case KEY2_MSK:
			dbg_puts("key 2 double press !!!" PTCR);
			break;
		case KEYUP_MSK:
			dbg_puts("key up double press !!!" PTCR);
			break;

		default:
			break;
		}
	}
}

void key_keep_any(void)
{
}

void key_release_any(void)
{
}

void key_idle(void)
{
}

/*****************************************************************************
 * @brief   key 0.
 *****************************************************************************/
void key0_press(void)
{
	dbg_puts("key 0 press down!" PTCR);
}

void key0_keep(void)
{
}

void key0_release(void)
{
	dbg_puts("key 0 press release!" PTCR);
	fun_list_run_once_pure(KEY_S0);
}

/*****************************************************************************
 * @brief   key 1.
 *****************************************************************************/
void key1_press(void)
{
	dbg_puts("key 1 press down!" PTCR);
}

void key1_keep(void)
{
}

void key1_release(void)
{
	dbg_puts("key 1 press release!" PTCR);
	fun_list_run_once_pure(KEY_S1);
}

/*****************************************************************************
 * @brief   key 2.
 *****************************************************************************/
void key2_press(void)
{
	dbg_puts("key 2 press down!" PTCR);
}

void key2_keep(void)
{
}

void key2_release(void)
{
	dbg_puts("key 2 press release!" PTCR);
	fun_list_run_once_pure(KEY_S2);
}

/*****************************************************************************
 * @brief   key up.
 *****************************************************************************/
void key_up_press(void)
{
	dbg_puts("key up press down!" PTCR);
}

void key_up_keep(void)
{
}

void key_up_release(void)
{
	dbg_puts("key up press release!" PTCR);
	fun_list_run_once_pure(KEY_UP);
}

/*****************************************************************************
 * @brief   key up 0.
 *****************************************************************************/
void key_up_key0_press(void)
{
	dbg_puts("key up and key0 press down!" PTCR);
}

void key_up_key0_keep(void)
{
}

void key_up_key0_release(void)
{
	dbg_puts("key up and key0 press release!" PTCR);
}

/*****************************************************************************
 * @brief   key up 2.
 *****************************************************************************/
void key_up_key2_press(void)
{
	dbg_puts("key up and key2 press down!" PTCR);
}

void key_up_key2_keep(void)
{
}

void key_up_key2_release(void)
{
	dbg_puts("key up and key2 press release!" PTCR);
}

/*****************************************************************************
 * @brief   key api
 *****************************************************************************/
const key_api_type key_api = {
	.key_down_any = key_down_any,
	.key_keep_any = key_keep_any,
	.key_obj = key_opt_list,
	.key_release_any = key_release_any,
	.key_idle = key_idle};

/*****************************************************************************
 * @brief   key list
 *****************************************************************************/
const key_opt_type key_opt_list[] = {
	{KEY0_MSK, key0_press, key0_keep, key0_release},
	{KEY1_MSK, key1_press, key1_keep, key1_release},
	{KEY2_MSK, key2_press, key2_keep, key2_release},
	{KEYUP_MSK, key_up_press, key_up_keep, key_up_release},
	{KEYUP_MSK | KEY0_MSK, key_up_key0_press, key_up_key0_keep, key_up_key0_release},
	{KEYUP_MSK | KEY2_MSK, key_up_key2_press, key_up_key2_keep, key_up_key2_release},
	{0},
};
